<?php

class JobController extends Controller
{

    private $_model;

    public $menu = array(
        array(
            'label' =>  '平台作业',
        ),
        array(
            'label' =>  '查询作业',
            'icon'  =>  'search',
            'url'   =>  array('/job/index', 'type'=>TaskType::Query),
        ),
        array(
            'label' =>  '传输作业',
            'icon'  =>  'random',
            'url'   =>  array('/job/index', 'type'=>TaskType::Transfer),
        ),
        array(
            'label' =>  '计算作业',
            'icon'  =>  'list-alt',
            'url'   =>  array('/job/index', 'type'=>TaskType::Compute),
        ),
    );
    
    /**
     * @return array action filters
     * 
     */
    public function filters()
    {
        return array(
            'accessControl', // perform access control for CRUD operations
        );
    }

	/**
	 * This is the default 'index' action that is invoked
	 * when an action is not explicitly requested by users.
	 */
	public function actionIndex()
	{
		$model=new Job;
		if(isset($_GET['Job'])) {
			$model->attributes=$_GET['Job'];
		}

        $criteria=new CDbCriteria(array(
            'with'  =>  array('user'),
        ));
        $criteria->compare('job_type', $_GET['type']);
        $criteria->addCondition('state <> '. JobState::Removed);
        if(Yii::app()->user->role == Role::Normal) {
            $criteria->addCondition('user_id='. Yii::app()->user->id);
        }
        
        if(Yii::app()->request->isPostRequest) {
            $criteria->compare('job_frequency', $_POST['Job']['job_frequency']);
            if(strlen($_POST['Job']['job_name']) > 0) {
            	$criteria->addSearchCondition('job_name', $_POST['Job']['job_name']);
            }
            if($_POST['Job']['submit_time'] != TimeSpan::Select) {
                if($_POST['Job']['submit_time'] == TimeSpan::Today) {
                    $submit_time = date('Y-m-d');
                }
                elseif($_POST['Job']['submit_time'] == TimeSpan::Week) {
                    $submit_time = DateHelper::weekFirstDay();
                }
                elseif($_POST['Job']['submit_time'] == TimeSpan::Month) {
                    $submit_time = DateHelper::monthFirstDay();
                }
                elseif($_POST['Job']['submit_time'] == TimeSpan::Year) {
                    $submit_time = DateHelper::yearFirstDay();
                }
                $criteria->addCondition('submit_time >=\''.$submit_time.'\''); 	
            }
        }
        
        $dataProvider = new CActiveDataProvider('Job', array(
            'criteria'=>$criteria,
            'sort'=>array(
                'defaultOrder'=>'job_id DESC',
            ),
        ));
        
        $this->render('index',array(
        	'model'=>$model,
            'type'=>$_GET['type'],
            'dataProvider' =>$dataProvider,
        ));
	}
	
 	/**
     *  Creates a new model.
     *  If creation is successful, the browser will be redirected to the 'view' page.
     * 
     */
    public function actionCreate($type)
    {
        $model=new Job;
        $model->job_type = $type;
        if(isset($_POST['Job']))
        {
            if($type == TaskType::Query) {
            	$status = $this->createQuery($model, $_POST['Job']);
            }
            elseif($type == TaskType::Transfer) {
              	$status = $this->createTransfer($model, $_POST['Job']);
            }
            elseif($type == TaskType::Compute) {
                $status = $this->createCompute($model, $_POST['Job']);
            }

            if($status) {
                Yii::log("create job[{$model->job_name}] successfully", CLogger::LEVEL_INFO, FRONTEND_LOG);
                $this->redirect(array('index', 'type'=>$type));          
            }
            else {
                Yii::log("create job[{$model->job_name}] failed", CLogger::LEVEL_ERROR, FRONTEND_LOG);
            }        
        }

        $this->render('create',array(
            'model'=>$model,
        	'type' =>$type,
        ));
    }

    public function actionUpdate() {
        $model = $this->loadModel();
        $job_params = CJSON::decode($model->job_param);
        $input = $job_params['inputs'][0];
        $output = $job_params['outputs'][0];
        if($model->job_type == JobType::Query) {
            $model->query_condition = $input['filter']['condition'];
            $model->output_name = $output['resource']['res_name'];
        }
        $model->system_id = $output['system_id'];

        if(isset($_POST['Job']))
        {
            $model->attributes=$_POST['Job'];
            if($model->save())
                $this->redirect(array('index'));
        }

        $this->render('create',array(
            'model'=>$model,
            'type'=>$model->job_type,
        ));
    }
    

    /**
     *   Deletes a particular model.
     *   If deletion is successful, the browser will be redirected to the 'index' page.
     */
    public function actionDelete()
    {
        if(Yii::app()->request->isPostRequest)
        {
        	$jobId = $_GET['job_id'];
        	$count = Job::model()->updateByPk($jobId, array('state'=>JobState::Removed));
        	if($count == 1) {
        		Yii::log("job[$jobId] was marked as removed successfully", CLogger::LEVEL_INFO, FRONTEND_LOG);
        	}
        	else {
        		Yii::log("job[$jobId] was marked as removed failed", CLogger::LEVEL_ERROR, FRONTEND_LOG);
        	}
            // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
            if(!isset($_GET['ajax'])) {
                $this->redirect(array('index'));
            }
        }
        else {
            throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
        }
    }

    public function actionRun() {
    	foreach ($_POST['autoId'] as $jobId) {
    		$job =Job::model()->findByPk($jobId);
	        $task = array(
				'job_id'	=>	$job['job_id'],
				'date'		=>	$_POST['Job']['task_date'],
				'state'		=>	TaskState::Waiting,
				'task_type'	=>	$job['job_type'],
				'workflow_name'=>	$job['workflow_name'],
				'frequency'	=>	$job['job_frequency'],
				'priority'	=>	$job['job_priority'],
			);
			TaskService::getInstance()->addTask($task);
    	}

    }

    public function actionAjaxDelete()
    {
        $autoIdAll = $_POST['autoId'];

        if(count($autoIdAll)>0) {
            $count = Job::model()->updateByPk($autoIdAll, array('state'=>JobState::Removed));
            $idList = implode(',', $autoIdAll);
       		if($count == count($autoIdAll)) {
        		Yii::log("jobs[$idList] was marked as removed successfully", CLogger::LEVEL_INFO, FRONTEND_LOG);
        	}
        	else {
        		Yii::log("jobs[$idList] was marked as removed failed", CLogger::LEVEL_ERROR, FRONTEND_LOG);
        	}
        }
    }

	/**
	 * This is the action to handle external exceptions.
	 */
	public function actionError()
	{
	    if($error=Yii::app()->errorHandler->error)
	    {
	    	if(Yii::app()->request->isAjaxRequest)
	    		echo $error['message'];
	    	else
	        	$this->render('error', $error);
	    }
	}
	
    private function createQuery($model, $job) {
        $model->attributes = $job;
		$model->user_id = Yii::app()->user->id;
		$model->job_type = JobType::Query;
		$model->state = JobState::Submit;
		$model->submit_time = date('Y-m-d H:i:s');
		$model->res_id = $job['res_id'];
		$model->output_name = $job['output_name'];
		$model->system_id = $job['system_id'];
		$model->workflow_name = 'AdhocHiveQuery';
        $model->trigger_param = CJSON::encode(array(
        	'auto'	=>	true,
        ));
        // Get input resource
        $resService = ResourceService::getInstance();
        $resource = $resService->getResourceById($model->res_id); 
        
        if($model->isNewRecord) {
        	$tmpResource = Resource::model()->findByAttributes(array(
    			'res_name'	=>	$model->output_name,
    		));
    		
    		if(isset($tmpResource)) {
				$this->alert("查询结果名 [{$model->output_name}] 已经被采用，请更换。");
			}
			return false;
        }
        
        // Create output resource
        $outputResource = array(
        	'res_name'	=>	$model->output_name,
        	'product_id'	=>	$resource['product_id'],
        	'res_type'	=>	ResourceType::QueryOutput,
        	'res_frequency'	=>	Frequency::None,
        	'quality_level'	=>	$resource['quality_level'],
        );
		$outputResId = $resService->addOutputResource($outputResource);
		if($outputResId === false) {
			 Yii::log("can't add output resource for [{$model->output_name}]", CLogger::LEVEL_ERROR, FRONTEND_LOG);
			return false;
		}	
        
        $outputResource['res_id'] = $outputResId;
        $jobParams = array(
            'inputs'    =>  array(
                array(
                	'resource'	=>	$resource,
                    'filter'	=>	array(
                        'select'	=>	array(
                            'tv_sec'	=>	array('type'=>'int', 'length'=>4),
                            'mid'	=>	array('type'=>'string', 'length'=>32),
                            'ip'	=>	array('type'=>'string', 'length'=>20),
                            'path'	=>	array('type'=>'string', 'length'=>1024),
                            'level'	=>	array('type'=>'int', 'length'=>4),
                        ),
                        'condition'	=>	$job['query_condition'],
                    ),
                ),
        	),
            'outputs'   =>  array(
                array(
                	'resource'	=>	$outputResource,
                	'system_id'	=>	$model->system_id,
                ),
        	),
        );
        $model->job_param = CJSON::encode($jobParams);        
		$status = $model->save();
		if($status) {
			$status = Resource::model()->updateByPk($outputResId, array('job_id'	=>	$model->job_id));
		}
		else {
			$this->alert("创建作业 [{$model->job_name}] 失败, 无法存入数据库。");
		}
		return $status;
    }
	
	private function createTransfer($model, $job) {
		$model->attributes = $job;
		$model->user_id = Yii::app()->user->id;
		$model->job_type = JobType::Transfer;
		$model->state = JobState::Submit;
		$model->submit_time = date('Y-m-d H:i:s');
		$model->res_id = $job['res_id'];
		$model->system_id = $job['system_id'];
		$model->workflow_name = 'DataXTransfer';
        $model->trigger_param = CJSON::encode(array(
        	'auto'	=>	true,
        ));
		
        // Get input resource
        $resService = ResourceService::getInstance();
        $resource = $resService->getResourceById($model->res_id); 
        
        $jobParams = array(
            'inputs'    =>  array(
                array(
                    'resource'	=>	$resource,
                    'filter'	=>	array(
                        'select'	=>	array(
                            'tv_sec'	=>	array('type'=>'int', 'length'=>4),
                            'mid'	=>	array('type'=>'string', 'length'=>32),
                            'ip'	=>	array('type'=>'string', 'length'=>20),
                            'path'	=>	array('type'=>'string', 'length'=>1024),
                            'level'	=>	array('type'=>'int', 'length'=>4),
                        ),
                    ),

                ),
        	),
            'outputs'   =>  array(
                array(
                	'resource'	=>	$resource,
                	'system_id'	=>	$model->system_id,
                ),
        	),
        );
        $model->job_param = CJSON::encode($jobParams);        
		return $model->save();
	}
	
    private function createCompute($model, $job) {
    	$model->attributes = $job;
		$model->user_id = Yii::app()->user->id;
		$model->job_type = JobType::Compute;
		$model->state = JobState::Submit;
		$model->submit_time = date('Y-m-d H:i:s');
		$model->trigger_param = CJSON::encode(array(
        	'auto'	=>	$model->trigger_way,
        ));
        $workflow = Workflow::model()->findByPk($job['workflow_name']);
        
        $model->workflow_name = $workflow['workflow_name'];
        $jobParams = array(
            'latest_start'	=>	$model->latest_start,
        );
        $model->job_param = CJSON::encode($jobParams);        
		return $model->save();
    }

    public function actionCondition() {

        $model=new Job;
        $flag=true;
        if(isset($_POST['Job'])) {
            $flag=false;
            $start_date = $_POST['Job']['start_date'];
            $end_date = $_POST['Job']['end_date'];
            $file_md5 = $_POST['Job']['file_md5'];

            echo "day >= '{$start_date}' and day <= '{$end_date}' and md5 = '{$file_md5}'";
        }
        if($flag) {
            Yii::app()->clientScript->scriptMap['jquery.js'] = false;
            $this->renderPartial('conditionDialog',array('model'=>$model,),false,true);
        }

    }

    /**
     *    Returns the data model based on the primary key given in the GET variable.
     *    If the data model is not found, an HTTP exception will be raised.
     */
    private function loadModel()
    {
        if($this->_model===null)
        {
            if(isset($_GET['job_id']))
            {
               $this->_model=Job::model()->findByPk($_GET['job_id']);
            }
            if($this->_model===null)
            {
                throw new CHttpException(404,'The requested page does not exist.');
            }
        }
        return $this->_model;
    }
}
